{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\nCompile CoreML Models\n=====================\n**Author**: `Joshua Z. Zhang <https://zhreshold.github.io/>`_,             `Kazutaka Morita <https://github.com/kazum>`_,             `Zhao Wu <https://github.com/FrozenGene>`_\n\nThis article is an introductory tutorial to deploy CoreML models with Relay.\n\nFor us to begin with, coremltools module is required to be installed.\n\nA quick solution is to install via pip\n\n.. code-block:: bash\n\n    pip install -U coremltools --user\n\nor please refer to official site\nhttps://github.com/apple/coremltools\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import tvm\nfrom tvm import te\nimport tvm.relay as relay\nfrom tvm.contrib.download import download_testdata\nimport coremltools as cm\nimport numpy as np\nfrom PIL import Image"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Load pretrained CoreML model\n----------------------------\nWe will download and load a pretrained mobilenet classification network\nprovided by apple in this example\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "model_url = \"https://docs-assets.developer.apple.com/coreml/models/MobileNet.mlmodel\"\nmodel_file = \"mobilenet.mlmodel\"\nmodel_path = download_testdata(model_url, model_file, module=\"coreml\")\n# Now you have mobilenet.mlmodel on disk\nmlmodel = cm.models.MLModel(model_path)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Load a test image\n------------------\nA single cat dominates the examples!\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "img_url = \"https://github.com/dmlc/mxnet.js/blob/main/data/cat.png?raw=true\"\nimg_path = download_testdata(img_url, \"cat.png\", module=\"data\")\nimg = Image.open(img_path).resize((224, 224))\n# Mobilenet.mlmodel's input is BGR format\nimg_bgr = np.array(img)[:, :, ::-1]\nx = np.transpose(img_bgr, (2, 0, 1))[np.newaxis, :]"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Compile the model on Relay\n---------------------------\nWe should be familiar with the process right now.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "target = \"llvm\"\nshape_dict = {\"image\": x.shape}\n\n# Parse CoreML model and convert into Relay computation graph\nmod, params = relay.frontend.from_coreml(mlmodel, shape_dict)\n\nwith tvm.transform.PassContext(opt_level=3):\n    lib = relay.build(mod, target, params=params)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Execute on TVM\n-------------------\nThe process is no different from other example\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from tvm.contrib import graph_executor\n\ndev = tvm.cpu(0)\ndtype = \"float32\"\nm = graph_executor.GraphModule(lib[\"default\"](dev))\n# set inputs\nm.set_input(\"image\", tvm.nd.array(x.astype(dtype)))\n# execute\nm.run()\n# get outputs\ntvm_output = m.get_output(0)\ntop1 = np.argmax(tvm_output.numpy()[0])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Look up synset name\n-------------------\nLook up prediction top 1 index in 1000 class synset.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "synset_url = \"\".join(\n    [\n        \"https://gist.githubusercontent.com/zhreshold/\",\n        \"4d0b62f3d01426887599d4f7ede23ee5/raw/\",\n        \"596b27d23537e5a1b5751d2b0481ef172f58b539/\",\n        \"imagenet1000_clsid_to_human.txt\",\n    ]\n)\nsynset_name = \"imagenet1000_clsid_to_human.txt\"\nsynset_path = download_testdata(synset_url, synset_name, module=\"data\")\nwith open(synset_path) as f:\n    synset = eval(f.read())\n# You should see the following result: Top-1 id 282 class name tiger cat\nprint(\"Top-1 id\", top1, \"class name\", synset[top1])"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.6.9"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}